#pragma once

#include "CXcpObjectBase.h"
#include "ICoreRenderTarget.h"
#include "CXcpObjectThreadSafeAddRefPolicy.h"

#include "ISimpleHashKey.h"
#include "ISimpleHashEntry.h"
#include "ISimpleHashMaker.h"
#include "xchainedmap.h"
#include "CUIElement.h"



class HWCompTreeNode;
class CHardwareCompositor;
class CMetaCompositor;
class HWWalk;
class CSimpleHash;


class CRenderTarget :
	public CXcpObjectBase<ICoreRenderTarget,CXcpObjectThreadSafeAddRefPolicy>
{

	class CAnimationTargetMappingHashKey :
		public ISimpleHashKey
	{
	private: 
		static void * operator new(size_t size);

	public: 
		virtual XUINT32 GetHash();
		void * GetHandle();
		virtual XINT32 EqualKeys(const struct ISimpleHashKey * pOther);
	private: 
		void * m_handle;
		XUINT32 m_hash;

	};

	class CAnimationTargetMapping :
		public CXcpObjectBase<ISimpleHashEntry,CXcpObjectThreadSafeAddRefPolicy>
	{
	public: 
		virtual XUINT32 AddRef();
		virtual XUINT32 Release();

	public: 
		CAnimationTargetMapping(CRenderTarget::CAnimationTargetMappingHashKey & key);
		CDependencyObject * GetTarget();
		void SetTarget(CDependencyObject * pTarget);
		virtual XUINT32 GetHash();
		virtual XINT32 EqualKeys(const struct ISimpleHashKey * pOther);
		virtual void OnRemove();
	private: 
		virtual ~CAnimationTargetMapping();
		CRenderTarget::CAnimationTargetMappingHashKey m_Key;
		CDependencyObject * m_pTarget;
	};

	class CAnimationTargetMappingCreator :
		public ISimpleHashMaker
	{

	public: 
		CAnimationTargetMappingCreator();
		~CAnimationTargetMappingCreator();
		virtual long Create(struct ISimpleHashKey * pKey, struct ISimpleHashEntry * * ppEntry);
	};

protected: 
	CRenderTarget(struct ICoreServices * pCore, struct ICoreCompositorScheduler * pICompositorScheduler, struct IPALGraphicsDeviceManager * pIGraphicsDeviceManager, struct IPALPresentTarget * pInitialPresentTarget);
	virtual ~CRenderTarget();
public: 
	virtual XUINT32 AddRef();
	virtual XUINT32 Release();
	virtual XUINT32 GetWidth();
	virtual XUINT32 GetHeight();
	virtual XBOOL IsRightAngleRotated();
	virtual HRESULT Retarget(struct IPALPresentTarget * pIPresentTarget);
	virtual HRESULT GetPresentTarget(struct IPALPresentTarget * * ppPresentTarget);
	virtual HRESULT Draw(struct ICoreServices * pCore, XBOOL fForceRedraw, struct XRECT_WH * prcDirtyRect);
	virtual CHardwareCompositor * GetPrimaryCompositor();
	CMetaCompositor * GetMetaCompositor();
	CCoreServices * GetTargetCore();
	HRESULT RegisterTargetMapping(CDependencyObject * pSource, CDependencyObject * pRedirectedSource);
	HRESULT GetTargetMapping(CDependencyObject * pSource, CDependencyObject * * ppRedirectedSource);
	HRESULT GetPropertyMapping(CDependencyProperty *, CDependencyProperty * *);
	HRESULT CreateDirectManipulationContentToCompositorTreeNodeMap(xchainedmap<CUIElement *,IObject *> * pMapUIElementToCompositorContent, xchainedmap<void *,HWCompTreeNode *> * * ppMapContentToCompositorTreeNode);
	CDependencyProperty * LookupRenderThreadDP(XUINT32 sourceIndex);
	void ResetTargetMappings();
	virtual HRESULT EnsureD2DDeviceAndFactory();
	virtual void GetD2DFactory(struct IPALAcceleratedGraphicsFactory * * ppD2DFactory);
	virtual void GetD2DDevice(struct IPALOptimizedGraphicsDevice * * ppD2DDevice);
	HWWalk * GetHwWalk();
	struct IPALGraphicsDeviceManager * GetGraphicsDeviceManager();
protected: 
	HRESULT Initialize(struct ICoreServices * pCore);
	HRESULT SubmitRetargetToCompositor();
	HRESULT EnsureRenderThreadCore();
	HRESULT DrawInternal(struct ICoreServices * pCore, XBOOL fForceRedraw, XBOOL wasDeviceLost, struct XRECT_WH * prcDirtyRect);
	struct ICoreCompositorScheduler * m_pICompositorScheduler;
	struct IPALGraphicsDeviceManager * m_pIGraphicsDeviceManager;
	struct IPALPresentTarget * m_pIPresentTarget;
	CMetaCompositor * m_pMetaCompositor;
	XBOOL m_requiresD2DDeviceAndFactory;
	struct IPALAcceleratedGraphicsFactory * m_pD2DFactory;
	struct IPALOptimizedGraphicsDevice * m_pD2DDevice;
	HWWalk * m_pHwWalk;
private: 
	CSimpleHash * m_pTargetMappingHashTable;
	CCoreServices * m_pRenderThreadCore;


};


